package utilities;

import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;

import screen.PaintPopup;
import font.BitmapFont;


import main.GameCanvas;
import main.NuoiThuMidlet;
import model.Command;
import model.IAction;

public class TField {
	public static final byte KEY_NUM0 = 0;
    public static final byte KEY_NUM1 = 1;
    public static final byte KEY_NUM2 = 2;
    public static final byte KEY_NUM3 = 3;
    public static final byte KEY_NUM4 = 4;
    public static final byte KEY_NUM5 = 5;
    public static final byte KEY_NUM6 = 6;
    public static final byte KEY_NUM7 = 7;
    public static final byte KEY_NUM8 = 8;
    public static final byte KEY_NUM9 = 9;
    public static final byte KEY_STAR = 10;
    public static final byte KEY_BOUND = 11;
    public static final byte KEY_UP = 12;
    public static final byte KEY_DOWN = 13;
    public static final byte KEY_LEFT = 14;
    public static final byte KEY_RIGHT = 15;
    public static final byte KEY_FIRE = 16;
    public static final byte KEY_LEFT_SOFTKEY = 17;
    public static final byte KEY_RIGHT_SOFTKEY = 18;
    public static final byte KEY_CLEAR = 19;
    public static final byte KEY_BACK = 20;
	public int x;
	public int y;
	public int width;
	public int height;
	public boolean isFocus;
	public boolean lockArrow = false;
	public boolean paintFocus = true;
	public boolean isReadonly = false;
	public static int typeXpeed = 2;
	private static final int[] MAX_TIME_TO_CONFIRM_KEY = { 18, 14, 11, 9, 6, 4, 2 };
	private static int CARET_HEIGHT = 0;
	private static final int CARET_WIDTH = 1;
	private static final int CARET_SHOWING_TIME = 5;
	private static final int TEXT_GAP_X = 5;
	private static final int MAX_SHOW_CARET_COUNER = 10;
	public static final int INPUT_TYPE_ANY = 0;
	public static final int INPUT_TYPE_NUMERIC = 1;
	public static final int INPUT_TYPE_PASSWORD = 2;
	public static final int INPUT_ALPHA_NUMBER_ONLY = 3;
	private static String[] print = { " 0", ".,@?!_1\"/$-():*+<=>;%&~#%^&*{}[];\'/1", "abc2áàảãạâấầẩẫậăắằẳẵặ2", "def3đéèẻẽẹêếềểễệ3", "ghi4íìỉĩị4", "jkl5", "mno6óòỏõọôốồổỗộơớờởỡợ6", "pqrs7", "tuv8úùủũụưứừửữự8", "wxyz9ýỳỷỹỵ9", "*", "#" };
	private static String[] printA = { "0", "1", "abc2", "def3", "ghi4", "jkl5", "mno6", "pqrs7", "tuv8", "wxyz9", "0", "0" };
	private String text = "";
	private String passwordText = "";
	public String paintedText = "";
	private int caretPos = 0;
	private int counter = 0;
	private int maxTextLenght = 500;
	private int offsetX = 0;
	private int lastKey = -1984;
	private int keyInActiveState = 0;
	private int indexOfActiveChar = 0;
	private int showCaretCounter = MAX_SHOW_CARET_COUNER;
	private int inputType = INPUT_TYPE_ANY;
	public static boolean isQwerty;
	public static int typingModeAreaWidth;
	public int mode = 0;
	public static final String modeNotify[] = { "abc", "Abc", "ABC", "123" };
	public static final int NOKIA = 0;
	public static final int MOTO = 1;
	public static final int ORTHER = 2;
	public static int changeModeKey = 11;
	public String sDefaust="";

	public static javax.microedition.lcdui.Canvas c;
	public static javax.microedition.midlet.MIDlet m;
	
	public void doChangeToTextBox() {
		final TextBox tb = new TextBox("", "", 500, TextField.ANY);
		tb.addCommand(new javax.microedition.lcdui.Command(GameResource.OK, 4, 0));
		tb.addCommand(new javax.microedition.lcdui.Command("Cancel", 3, 0));
		tb.setCommandListener(new CommandListener() {
			public void commandAction(javax.microedition.lcdui.Command cmd, Displayable arg1) {
				if (cmd.getLabel().equals(GameResource.OK)) {
					setText(tb.getString());
				}
				Display.getDisplay(m).setCurrent(c);
				c.setFullScreenMode(true);
			}
		});
		try {
			if (inputType == INPUT_TYPE_PASSWORD)
				tb.setConstraints(TextField.PASSWORD);
			else if (inputType == INPUT_TYPE_NUMERIC)
				tb.setConstraints(TextField.NUMERIC);
			else
				tb.setConstraints(TextField.ANY);
		} catch (Exception e) {
			e.printStackTrace();
		}
		tb.setString(getText());
		tb.setMaxSize(maxTextLenght);
		Display.getDisplay(m).setCurrent(tb);
	}

	public static void setVendorTypeMode(int mode) {
		if (mode == MOTO) {
			print[0] = "0";
			print[10] = " *";
			print[11] = "#";
			changeModeKey = '#';
		} else if (mode == NOKIA) {
			print[0] = " 0";
			print[10] = "*";
			print[11] = "#";
			changeModeKey = '#';
		} else if (mode == ORTHER) {
			print[0] = "0";
			print[10] = "*";
			print[11] = " #";
			changeModeKey = '*';
		}
	}

	public Command cmdClear;

	private void init() {
		CARET_HEIGHT = BitmapFont.m_bmNormalFont.getHeight() + 1;
		
		cmdClear = new Command(GameResource.del, new IAction() {
			public void perform() {
				clear();
			}
		});
		
		typingModeAreaWidth = 0;// BitmapFont.m_bmNormalFont.stringWidth("ABC");
		
		if(c == null){
			c = GameCanvas.instance;
			m = NuoiThuMidlet.instance;
		}
	}

	public TField() {
		text = "";
		init();
	}

	public TField(String text, int maxLen, int inputType) {
		this.text = text;
		this.maxTextLenght = maxLen;
		this.inputType = inputType;
		init();
	}

	public void clear() {
		if (caretPos > 0 && text.length() > 0) {
			text = text.substring(0, caretPos - 1) + text.substring(caretPos, text.length());
			caretPos--;
			setOffset();
			setPasswordTest();
		}
	}

	public void setOffset() {
		if (inputType == INPUT_TYPE_PASSWORD)
			paintedText = passwordText;
		else
			paintedText = text;
		if (offsetX < 0 && BitmapFont.m_bmNormalFont.stringWidth(paintedText) + offsetX < width - TEXT_GAP_X - 13 - typingModeAreaWidth)
			offsetX = width - 10 - typingModeAreaWidth - BitmapFont.m_bmNormalFont.stringWidth(paintedText);
		if (offsetX + BitmapFont.m_bmNormalFont.stringWidth(paintedText.substring(0, caretPos)) <= 0) {
			offsetX = -BitmapFont.m_bmNormalFont.stringWidth(paintedText.substring(0, caretPos));
			offsetX = offsetX + 40;
		} else if (offsetX + BitmapFont.m_bmNormalFont.stringWidth(paintedText.substring(0, caretPos)) >= width - 12 - typingModeAreaWidth)
			offsetX = width - 10 - typingModeAreaWidth - BitmapFont.m_bmNormalFont.stringWidth(paintedText.substring(0, caretPos)) - 2 * TEXT_GAP_X;
		if (offsetX > 0)
			offsetX = 0;
	}

	private void keyPressedAny(int keyCode) {
		String[] print;
		if (inputType == INPUT_TYPE_PASSWORD || inputType == INPUT_ALPHA_NUMBER_ONLY)
			print = printA;
		else
			print = TField.print;
		if (keyCode == lastKey) {
			indexOfActiveChar = (indexOfActiveChar + 1) % print[keyCode - '0'].length();
			char c = print[keyCode - '0'].charAt(indexOfActiveChar);
			if (mode == 0)
				c = Character.toLowerCase(c);
			else if (mode == 1) {
				c = Character.toUpperCase(c);
			} else if (mode == 2) {
				c = Character.toUpperCase(c);
			} else {
				c = print[keyCode - '0'].charAt(print[keyCode - '0'].length() - 1);
			}
			String ttext = text.substring(0, caretPos - 1) + c;
			if (caretPos < text.length())
				ttext = ttext + text.substring(caretPos, text.length());
			text = ttext;
			keyInActiveState = MAX_TIME_TO_CONFIRM_KEY[typeXpeed];
			setPasswordTest();
		} else {
			if (text.length() < maxTextLenght) {
				if (mode == 1 && lastKey != -1984)
					mode = 0;
				indexOfActiveChar = 0;
				char c = print[keyCode - '0'].charAt(indexOfActiveChar);
				if (mode == 0)
					c = Character.toLowerCase(c);
				else if (mode == 1) {
					c = Character.toUpperCase(c);
				} else if (mode == 2) {
					c = Character.toUpperCase(c);
				} else {
					c = print[keyCode - '0'].charAt(print[keyCode - '0'].length() - 1);
				}
				String ttext = text.substring(0, caretPos) + c;
				if (caretPos < text.length())
					ttext = ttext + text.substring(caretPos, text.length());
				text = ttext;
				keyInActiveState = MAX_TIME_TO_CONFIRM_KEY[typeXpeed];
				caretPos++;
				setPasswordTest();
				setOffset();
			}
		}
		lastKey = keyCode;
	}

	private void keyPressedAscii(int keyCode) {
		if (inputType == INPUT_TYPE_PASSWORD || inputType == INPUT_ALPHA_NUMBER_ONLY) {
			if ((keyCode < '0' || keyCode > '9') && (keyCode < 'A' || keyCode > 'Z') && (keyCode < 'a' || keyCode > 'z')) {
				return;
			}
		}
		if (text.length() < maxTextLenght) {
			String ttext = text.substring(0, caretPos) + (char) keyCode;
			if (caretPos < text.length())
				ttext = ttext + text.substring(caretPos, text.length());
			text = ttext;
			caretPos++;
			setPasswordTest();
			setOffset();
		}
	}

	int holdCount;

	public void keyHold(int keyCode) {
		holdCount++;
		if (holdCount > 15 && !isQwerty && keyCode < print.length) {
			clear();
			keyPressedAscii(print[keyCode].charAt(print[keyCode].length() - 1));
			keyInActiveState = MAX_TIME_TO_CONFIRM_KEY[typeXpeed];
			holdCount = 0;
		}
		if (holdCount > 20) {
			if (keyCode == KEY_CLEAR) {
				setText("");
				holdCount = 0;
			}
		}
	}

	public boolean keyPressed(int keyCode) {
		if (keyCode == 8 || keyCode == -8 || keyCode == 204) {
			clear();
			return true;
		}
		holdCount = 0;
		if (keyCode >= 'A' && keyCode <= 'z') {
			isQwerty = true;
			typingModeAreaWidth = 0;
		}
		if (isQwerty) {
			// Nokia E71 character '_' by 2x '-'
			if (keyCode == '-') {
				if (keyCode == lastKey && keyInActiveState < MAX_TIME_TO_CONFIRM_KEY[typeXpeed]) {
					text = text.substring(0, caretPos - 1) + '_';
					this.paintedText = text;
					setPasswordTest();
					setOffset();
					lastKey = -1984;
					return false;
				}
				lastKey = '-';
			}
			if (keyCode >= 32) {
				keyPressedAscii(keyCode);
				return false; // swallow
			}
		}
		if (keyCode == changeModeKey) {
			mode++;
			if (mode > 3)
				mode = 0;
			keyInActiveState = 1;
			lastKey = keyCode;
			return false; // swallow
		}
		if (keyCode == '*')
			keyCode = '9' + 1;
		if (keyCode == '#')
			keyCode = '9' + 2;
		if (keyCode >= '0' && keyCode <= '9' + 2) {
			if (inputType == INPUT_TYPE_ANY || inputType == INPUT_TYPE_PASSWORD || inputType == INPUT_ALPHA_NUMBER_ONLY)
				keyPressedAny(keyCode);
			else if (inputType == INPUT_TYPE_NUMERIC) {
				keyPressedAscii(keyCode);
				keyInActiveState = 1;
			}
		} else {
			indexOfActiveChar = 0;
			lastKey = -1984;
			if (keyCode == KEY_LEFT && !lockArrow) {
				if (caretPos > 0) {
					caretPos--;
					setOffset();
					showCaretCounter = MAX_SHOW_CARET_COUNER;
					return false;
				}
			} else if (keyCode == KEY_RIGHT && !lockArrow) {
				if (caretPos < text.length()) {
					caretPos++;
					setOffset();
					showCaretCounter = MAX_SHOW_CARET_COUNER;
					return false;
				}
			} else if (keyCode == KEY_CLEAR) {
				clear();
				return false;
			} else {
				lastKey = keyCode;
			}
		}
		return true; // Not swallow
	}

	public void pointerRelease(final int px, final int py) {
		doChangeToTextBox();
	}

	
	public void paintPrice(Graphics g, int x, int y, boolean isKeyArrow, String str){
		if(isKeyArrow)
			paintedText = str;
		else
			paintedText = text;	
		//g.setClip(0, 0, GameCanvas.w, GameCanvas.h);
		
		//g.setClip(x + 3, y + 1, width - (typingModeAreaWidth) - 8, height - 4);
		
		g.setColor(0);		
		if(paintedText.equals("")){
			BitmapFont.drawOutlinedString(g, sDefaust, TEXT_GAP_X + offsetX + x, y + (height - BitmapFont.m_bmNormalFont.getHeight()) / 2, 0xffff00, 0x000000, Graphics.LEFT);
		}else
			BitmapFont.drawOutlinedString(g, paintedText, TEXT_GAP_X + offsetX + x, y + (height - BitmapFont.m_bmNormalFont.getHeight()) / 2, 0xffff00, 0x000000, Graphics.LEFT);
		
	}
	
	public void paint(Graphics g) {
		boolean isFocus = isFocused();
		if (inputType == INPUT_TYPE_PASSWORD)
			paintedText = passwordText;
		else
			paintedText = text;	
		g.setClip(0, 0, GameCanvas.w, GameCanvas.h);
		
		PaintPopup.paintInputTf(g, isFocus, x, y, width, height);

		
		g.setClip(x + 3, y + 1, width - (typingModeAreaWidth) - 8, height - 4);
		
		g.setColor(0);		
		if(paintedText.equals("")){
			BitmapFont.drawNormalFont(g, sDefaust, TEXT_GAP_X + offsetX + x, y + (height - BitmapFont.m_bmNormalFont.getHeight()) / 2, 0xffffff, Graphics.LEFT);
		}else
			BitmapFont.drawNormalFont(g, paintedText, TEXT_GAP_X + offsetX + x, y + (height - BitmapFont.m_bmNormalFont.getHeight()) / 2, 0xffffff, Graphics.LEFT);
		
		if (isFocused() && !isReadonly) {
			if (keyInActiveState == 0 && (showCaretCounter > 0 || (counter / CARET_SHOWING_TIME) % 2 == 0)) {
				g.setColor(0xFFFFFF);				
				g.fillRect(TEXT_GAP_X + offsetX + x + BitmapFont.m_bmNormalFont.stringWidth(paintedText.substring(0, caretPos)) - CARET_WIDTH+1, y + (height - CARET_HEIGHT) / 2 + 1, CARET_WIDTH, CARET_HEIGHT);
			}
		}
	}

	private boolean isFocused() {
		return isFocus;
	}

	private void setPasswordTest() {
		if (inputType == INPUT_TYPE_PASSWORD) {
			passwordText = "";
			for (int i = 0; i < text.length(); i++)
				passwordText = passwordText + "*";
			if (keyInActiveState > 0 && caretPos > 0)
				passwordText = passwordText.substring(0, caretPos - 1) + text.charAt(caretPos - 1) + passwordText.substring(caretPos, passwordText.length());
		}
	}
	public static boolean setNormal(char ch){
		if ((ch < '0' || ch > '9') && (ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
			return false;
		}
		return true;
	}
	public void paintFocus(Graphics g) {
	}

	public void update() {
		counter++;
		if (keyInActiveState > 0) {
			keyInActiveState--;
			if (keyInActiveState == 0) {
				indexOfActiveChar = 0;
				if (mode == 1 && lastKey != changeModeKey)
					mode = 0;
				lastKey = -1984;
				setPasswordTest();
			}
		}
		if (showCaretCounter > 0)
			showCaretCounter--;
		
		if (GameCanvas.isPointerClick&&GameCanvas.currentDialog==null){			
			setTextBox();
		}
	}
	
	public void setTextBox() {				
		if (GameCanvas.isPointer(x, y, width, height)) {
			if(!isFocus)
				isFocus=true;
			else
				doChangeToTextBox();			
		} else
			isFocus = false;
	}
	
	public String getText() {
		return text;
	}

	public void setText(String text) {
		if (text == null)
			return;
		lastKey = -1984;
		keyInActiveState = 0;
		indexOfActiveChar = 0;
		this.text = text;
		this.paintedText = text;
		setPasswordTest();
		caretPos = text.length();
		setOffset();
	}

	public void insertText(String text) {
		this.text = this.text.substring(0, caretPos) + text + this.text.substring(caretPos);
		setPasswordTest();
		caretPos += text.length();
		setOffset();
	}

	public int getMaxTextLenght() {
		return maxTextLenght;
	}

	public void setMaxTextLenght(int maxTextLenght) {
		this.maxTextLenght = maxTextLenght;
	}

	public int getIputType() {
		return inputType;
	}

	public void setIputType(int iputType) {
		this.inputType = iputType;
	}
}

